package com.danceforyou.user.service.impl;

import com.danceforyou.common.model.ConfigDO;
import com.danceforyou.common.restful.exception.BizException;
import com.danceforyou.common.restful.exception.BizExceptionEnum;
import com.danceforyou.common.service.ConfigService;
import com.danceforyou.common.service.OperationService;
import com.danceforyou.common.service.impl.BaseServiceImpl;
import com.danceforyou.common.util.*;
import com.danceforyou.common.vo.SqlOrderEnum;
import com.danceforyou.user.dao.UserDAO;
import com.danceforyou.user.model.RoleDO;
import com.danceforyou.user.model.UserDO;
import com.danceforyou.user.service.RoleService;
import com.danceforyou.user.service.UserService;
import com.danceforyou.user.vo.RoleVO;
import com.danceforyou.user.vo.UserVO;
import com.danceforyou.websocket.BacklogSocket;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* 类名称：UserServiceImpl
* 创建人：danceforyou
* 创建时间：2021年01月10日
* 版本号：1.0v
*/
@Service("userService")
public class UserServiceImpl extends BaseServiceImpl<Long, UserDO, UserVO, UserDAO> implements UserService {
    @Autowired
    private UserDAO userDAO;
    @Autowired
    private ConfigService configService;
    @Autowired
    private OperationService operationService;
    @Autowired
    private RoleService roleService;
    @Autowired(required = false)
    private HttpSession session;

    private ClientSession clientSession = new ClientSession();

    @Override
    public UserDAO getDao() {
        return userDAO;
    }

    @Override
    public void saveLogin(String account, String password, String requestIP) {
        // 获取配置（密码错误登录次数）
        ConfigDO config = configService.getByProperty("configText", Constants.CONFIG_MAX_LOGIN_FAILED_NUMBER);
        int maxLoginFailed = 5;//默认五次
        if (config != null && !StringUtil.isBlank(config.getConfigValue())) {
            maxLoginFailed = Integer.parseInt(config.getConfigValue());
        }
        Hashtable<String, Integer> loginMap = clientSession.getLoginNumber();
        int loginFailed = loginMap.get(requestIP +"_"+ account) == null ? 0 : loginMap.get(requestIP +"_"+ account);
        if (loginFailed >= maxLoginFailed) {
            throw new BizException("账户已被锁定，请在10分钟后重新登录");
        }
        UserDO user = this.getByProperty("account", account, "isDelete", SqlOrderEnum.DESC);
        AssertUtil.notNull(user, "用户信息不存在");
        AssertUtil.isTrue(!user.getIsDelete(), "用户信息不存在");
        AssertUtil.isTrue(user.getStatus() == Constants.USER_STATUS_ENABLE, "该用户已停用");
        if (user.getPassword().equals(MD5.MD5Encode(password))) {
            loginMap.remove(requestIP +"_"+ account);
            // 获取员工岗位
            RoleDO role = roleService.getById(user.getRoleId());
            AssertUtil.notNull(role, "岗位信息不存在，请联系管理员");
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            while (role.getPId() > 0) {
                role = roleService.getById(role.getPId());
            }
            if (role.getId() == Constants.ROLE_GLB_ID) {
                roleVO.setRoleType(Constants.ROLE_GLB_CODE);
            } else if (role.getId() == Constants.ROLE_MJB_ID) {
                roleVO.setRoleType(Constants.ROLE_MJB_CODE);
            } else if (role.getId() == Constants.ROLE_XSB_ID) {
                roleVO.setRoleType(Constants.ROLE_XSB_CODE);
            } else if (role.getId() == Constants.ROLE_CWB_ID) {
                roleVO.setRoleType(Constants.ROLE_CWB_CODE);
            }
            //判断员工是否为专员
            if (roleVO.getRoleType().equals(Constants.ROLE_XSB_CODE) || roleVO.getRoleType().equals(Constants.ROLE_MJB_CODE)) {
                roleVO.setIsCommissioner(roleVO.getPId() != Constants.ROLE_XSB_ID && roleVO.getPId() != Constants.ROLE_MJB_ID);
            } else {
                roleVO.setIsCommissioner(false);
            }
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            userVO.setRole(roleVO);
            userVO.setSessionUuid(UUID.randomUUID().toString());
            operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_LOGIN, user, requestIP);
            session.setAttribute(Constants.SESSION_USER, userVO);
            session.setMaxInactiveInterval(Constants.SESSION_INTERVAL);
        } else {
            loginFailed ++;
            loginMap.put(requestIP +"_"+ account, loginFailed);
            clientSession.setLoginNumber(loginMap);
            //TimerTask实现10分钟后从session中删除错误次数
            final Timer timer=new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    Hashtable<String, Integer> loginNumber = clientSession.getLoginNumber();
                    loginNumber.put(requestIP +"_"+ account, 0);
                    clientSession.setLoginNumber(loginNumber);
                    timer.cancel();
                }
            },10*60*1000);
            throw new BizException("账户或密码错误！");
        }
    }

    @Override
    public void saveUserInfo(UserDO user) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO temp = this.getByProperty("account", user.getAccount(), "isDelete", SqlOrderEnum.DESC);
        AssertUtil.isTrue(temp == null || temp.getIsDelete(), "该账号已存在，请重新输入");
        // 保存员工信息
        user.setPassword(MD5.MD5Encode("123456"));
        user.setStatus(Constants.USER_STATUS_ENABLE);
        user.setIsRset(true);
        userDAO.insert(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_ADD, loginUser, null);
    }

    @Override
    public void updateUserInfo(UserDO user) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO temp = userDAO.getById(user.getId());
        AssertUtil.notNull(temp, "信息不存在");
        user.setAccount(null);
        userDAO.update(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_EDIT, loginUser, null);
    }

    @Override
    public void deleteUserInfoByIds(String ids) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        for (String id : idArr) {
            UserDO user = userDAO.getById(Long.valueOf(id));
            AssertUtil.notNull(user, "信息不存在");
            userDAO.setDeleteById(user.getId());
            // 记录操作日志
            operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_DELETE, loginUser, null);
        }
    }

    @Override
    public void setUserDisable(Long userId) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO user = userDAO.getById(userId);
        AssertUtil.notNull(user, "信息不存在");
        user.setStatus(Constants.USER_STATUS_DISABLE);
        userDAO.update(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_DISABLE, loginUser, null);
    }

    @Override
    public void setUserEnable(Long userId) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO user = userDAO.getById(userId);
        AssertUtil.notNull(user, "信息不存在");
        user.setStatus(Constants.USER_STATUS_ENABLE);
        userDAO.update(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_ENABLE, loginUser, null);
    }

    @Override
    public void setUserPasswordReset(Long userId) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO user = userDAO.getById(userId);
        AssertUtil.notNull(user, "信息不存在");
        user.setPassword(MD5.MD5Encode("123456"));
        userDAO.update(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_RESETPWD, loginUser, null);
    }

    @Override
    public void updateUserPassword(String oldPassword, String newPassword) {
        UserDO loginUser = (UserDO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO user = userDAO.getById(loginUser.getId());
        AssertUtil.notNull(user, "信息不存在");
        AssertUtil.isTrue(user.getPassword().equals(MD5.MD5Encode(oldPassword)), "原密码错误，操作失败");
        user.setPassword(MD5.MD5Encode(newPassword));
        user.setIsRset(false);
        userDAO.update(user);
        // 记录操作日志
        operationService.saveOperation(Constants.OPER_TABLE_USER, user.getId(), Constants.OPER_SETPWD, loginUser, null);
    }

    @Override
    public List<UserVO> listAllUsersByCustomerId(Long customerId) {
        return userDAO.listAllUsersByCustomerId(customerId);
    }

    @Override
    public UserDO getSuperiorUser(Long roleId) {
        RoleDO role = roleService.getById(roleId);
        AssertUtil.notNull(role, "岗位信息不存在");
        RoleDO superiorRole = roleService.getById(role.getPId());
        AssertUtil.notNull(superiorRole, "岗位信息不存在");
        return this.getByProperty("roleId", superiorRole.getId(), "id", SqlOrderEnum.ASC);
    }
}
